package top.itaso.app.ui.floating;

import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import top.itaso.lib.alog.ALog;

/**
 * @Description:
 * @Author itsdf07
 * @E-Mail 923255742@qq.com
 * @Github https://github.com/itsdf07
 * @Date 2022/01/25
 */
public class FloatingWindowDragListener implements View.OnTouchListener {
    private static final String TAG = FloatingWindowDragListener.class.getSimpleName();
    /**
     * 手指按下拖拽一定距离时进行 View 位置刷新以表示窗口拖动，可以理解为防抖阀值
     */
    private final int MOVE_COORDINATE_THRESHOLD = 25;
    /**
     * 悬浮窗 配置参数
     */
    private WindowManager.LayoutParams mFloatingWindowLayoutParams;

    private View mFloatingWindowView;
    private DisplayMetrics metrics = new DisplayMetrics();
    private WindowManager windowManager;

    //记录按下时窗口左上角坐标的当时位置
    private float mX;
    private float mY;

    /**
     * 悬浮窗口左上角的拖动 X 方向的 最小/最大 位置
     */
    private int mViewLayoutParamsMinX, mViewLayoutParamsMaxX;
    /**
     * 悬浮窗口左上角的拖动 Y 方向的 最小/最大 位置
     */
    private int mViewLayoutParamsMinY, mViewLayoutParamsMaxY;

    //记录按下时的屏幕坐标，用于与mXMoveInScreen进行计算移动量，在与 MOVE_COORDINATE_THRESHOLD 做参照用于控制是否刷新UI的拖动
    private int mXDownInScreen;//触点按下时的位置
    private int mYDownInScreen;
    private int mXMoveInScreen;//移动过程中触点的实时位置
    private int mYMoveInScreen;

    private boolean isMoved = false;
    private boolean isPortrait;


    public FloatingWindowDragListener(WindowManager windowManager, WindowManager.LayoutParams viewParams, View rootView, boolean isPortrait) {
        this.windowManager = windowManager;
        this.mFloatingWindowLayoutParams = viewParams;
        this.mFloatingWindowView = rootView;
        this.isPortrait = isPortrait;
        mViewLayoutParamsMinX = mViewLayoutParamsMinY = 0;
        calcMaxMoveDistance(isPortrait);

    }

    /**
     * getX():触摸点到当前View左边缘的距离.
     * getRawX():触摸点到屏幕左边缘的距离.
     *
     * @param v
     * @param event
     * @return
     */
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (mFloatingWindowView == null) {
            return false;
        }
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mX = mFloatingWindowLayoutParams.x;
                mY = mFloatingWindowLayoutParams.y;
                mXDownInScreen = (int) event.getRawX();
                mYDownInScreen = (int) event.getRawY();
                isMoved = false;
                break;
            case MotionEvent.ACTION_MOVE:
                mXMoveInScreen = (int) event.getRawX();
                mYMoveInScreen = (int) event.getRawY();

                int deltaX = Math.abs(mXMoveInScreen - mXDownInScreen);
                int deltaY = Math.abs(mYMoveInScreen - mYDownInScreen);
                if (deltaX >= MOVE_COORDINATE_THRESHOLD || deltaY >= MOVE_COORDINATE_THRESHOLD) {
                    mFloatingWindowLayoutParams.x = (int) (mXMoveInScreen - mXDownInScreen + mX);
                    mFloatingWindowLayoutParams.y = (int) (mYMoveInScreen - mYDownInScreen + mY);

//                    //限制不能拖拽到手机屏幕外
                    if (mFloatingWindowLayoutParams.x < mViewLayoutParamsMinX) {
                        mFloatingWindowLayoutParams.x = mViewLayoutParamsMinX;
                    }
                    if (mFloatingWindowLayoutParams.x > mViewLayoutParamsMaxX) {
                        mFloatingWindowLayoutParams.x = mViewLayoutParamsMaxX;
                    }
                    if (mFloatingWindowLayoutParams.y < mViewLayoutParamsMinY) {
                        mFloatingWindowLayoutParams.y = mViewLayoutParamsMinY;
                    }
                    if (mFloatingWindowLayoutParams.y > mViewLayoutParamsMaxY) {
                        mFloatingWindowLayoutParams.y = mViewLayoutParamsMaxY;
                    }
                    windowManager.updateViewLayout(mFloatingWindowView, mFloatingWindowLayoutParams);
                    mFloatingWindowView.setPressed(false);
                    isMoved = true;
                }
                break;
            case MotionEvent.ACTION_UP:
                if (isMoved) {
                    return true;
                }
                break;
            default:
                break;
        }
        return false;
    }


    /**
     * 计算悬浮窗口拖拽的最大 X/Y 方向的距离
     *
     * @param isPortrait
     */
    private void calcMaxMoveDistance(boolean isPortrait) {
        ALog.dTag(TAG, "calcMaxMoveDistance: >>>>>>viewWidth=" + mFloatingWindowLayoutParams.width + ",viewHeight=" + mFloatingWindowLayoutParams.height);
        this.isPortrait = isPortrait;
        windowManager.getDefaultDisplay().getMetrics(metrics);
        //扣除悬浮窗口的宽高，确保在拖拽过程中，悬浮窗口不会被拖到屏幕外
        mViewLayoutParamsMaxX = metrics.widthPixels - mFloatingWindowLayoutParams.width;
        mViewLayoutParamsMaxY = metrics.heightPixels - mFloatingWindowLayoutParams.height;
    }
}
